package org.wiztools.commons.feed;

import java.io.Serializable;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 *
 * @author subhash
 */
public final class Feed implements Cloneable, Serializable {

    private String title;
    private URL url;
    private String description;
    private List<FeedEntry> entries;
    private Map<String, Serializable> extensions = new HashMap<String, Serializable>();

    public void addExtension(String key, Serializable value){
        extensions.put(key, value);
    }

    public Map<String, Serializable> getExtensions(){
        return Collections.unmodifiableMap(extensions);
    }

    public Serializable getExtension(final String key){
        return extensions.get(key);
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public List<FeedEntry> getEntries() {
        List<FeedEntry> dupEntries = new ArrayList<FeedEntry>();
        if (entries != null) {
            for (FeedEntry entry : entries) {
                FeedEntry e = (FeedEntry) entry.clone();
                dupEntries.add(e);
            }
            return dupEntries;
        } else {
            return null;
        }

    }

    public void setEntries(List<FeedEntry> entries) {
        this.entries = entries;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public URL getUrl() {
        return url;
    }

    public void setUrl(URL url) {
        this.url = url;
    }

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append("{").append(title).append(", ");
        sb.append(description).append(", ");
        sb.append(url).append(", ");
        sb.append(extensions).append(", ");
        sb.append(entries).append("}");
        return sb.toString();
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final Feed other = (Feed) obj;
        if ((this.title == null) ? (other.title != null) : !this.title.equals(other.title)) {
            return false;
        }
        if (this.url != other.url && (this.url == null || !this.url.equals(other.url))) {
            return false;
        }
        if ((this.description == null) ? (other.description != null) : !this.description.equals(other.description)) {
            return false;
        }
        if (this.entries != other.entries && (this.entries == null || !this.entries.equals(other.entries))) {
            return false;
        }
        if (this.extensions != other.extensions && (this.extensions == null || !this.extensions.equals(other.extensions))) {
            return false;
        }
        return true;
    }

    @Override
    public int hashCode() {
        int hash = 7;
        hash = 83 * hash + (this.title != null ? this.title.hashCode() : 0);
        hash = 83 * hash + (this.url != null ? this.url.hashCode() : 0);
        hash = 83 * hash + (this.description != null ? this.description.hashCode() : 0);
        hash = 83 * hash + (this.entries != null ? this.entries.hashCode() : 0);
        hash = 83 * hash + (this.extensions != null ? this.extensions.hashCode() : 0);
        return hash;
    }

    @Override
    public Object clone() {
        Feed feed = new Feed();
        feed.setTitle(title);
        feed.setDescription(description);
        feed.setUrl(url);
        if (entries != null) {
            List<FeedEntry> outEntries = new ArrayList<FeedEntry>();
            for (FeedEntry entry : entries) {
                FeedEntry e = (FeedEntry) entry.clone();
                outEntries.add(e);
            }
            feed.setEntries(outEntries);
        }
        for(String key: extensions.keySet()){
            feed.addExtension(key, extensions.get(key));
        }
        return feed;
    }
}
